package com.xuecheng.search.service;

import com.xuecheng.framework.domain.course.CoursePub;
import com.xuecheng.framework.domain.search.CourseSearchParam;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.QueryResult;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.naming.directory.SearchResult;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

/**
 * @author zhang kun
 * @Classname ServiceTest
 * @Description TODO
 * @Date 2021/7/23 21:16
 */
public class ServiceTest {
    @Value("${xuecheng.course.index}")
    private String index;
    @Value("${xuecheng.media.index}")
    private String media_index;
    @Value("${xuecheng.course.type}")
    private String type;
    @Value("${xuecheng.media.type}")
    private String media_type;
    @Value("${xuecheng.course.source_field}")
    private String source_field;
    @Value("${xuecheng.media.source_field}")
    private String media_source_field;

    @Autowired
    RestHighLevelClient restHighLevelClient;

    public QueryResponseResult<CoursePub> list(int page, int size, CourseSearchParam courseSearchParam){
        if(courseSearchParam == null){
            courseSearchParam = new CourseSearchParam();
        }
        SearchRequest searchRequest = new SearchRequest(index);
        searchRequest.types(type);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        String[] source_field_array = source_field.split(",");
        searchSourceBuilder.fetchSource(source_field_array, new String[]{});
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        QueryResult<CoursePub> queryResult = new QueryResult();
        if(StringUtils.isNotEmpty(courseSearchParam.getKeyword())){
            MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(courseSearchParam.getKeyword(), "name", "description", "teachplan").minimumShouldMatch("70%")
                    .field("name",10);
            boolQueryBuilder.must(multiMatchQueryBuilder);
            if(StringUtils.isNotEmpty(courseSearchParam.getMt())){
                //根据一级分类
                boolQueryBuilder.filter(QueryBuilders.termQuery("mt",courseSearchParam.getMt()));
            }
            if(StringUtils.isNotEmpty(courseSearchParam.getSt())){
                //根据二级分类
                boolQueryBuilder.filter(QueryBuilders.termQuery("st",courseSearchParam.getSt()));
            }
            if(StringUtils.isNotEmpty(courseSearchParam.getGrade())){
                //根据难度等级
                boolQueryBuilder.filter(QueryBuilders.termQuery("grade",courseSearchParam.getGrade()));
            }
            boolQueryBuilder.filter(QueryBuilders.termQuery("grade",courseSearchParam.getGrade()));
            searchSourceBuilder.query(boolQueryBuilder);
            if(page <= 0){
                page = 1;
            }
            if(size <=0 ){
                size = 12;
            }

            int form = (page-1) *size;
            searchSourceBuilder.from(form);
            searchSourceBuilder.size(size);

            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.preTags("<font class='eslight'>");
            highlightBuilder.postTags("</font>");
            highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
            searchSourceBuilder.highlighter(highlightBuilder);
            searchRequest.source(searchSourceBuilder);

            ArrayList<CoursePub> list = new ArrayList<>();
            try{
                SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
                SearchHits hits = searchResponse.getHits();
                long totalHits = hits.getTotalHits();
                queryResult.setTotal(totalHits);
                SearchHit[] searchHits = hits.getHits();
                for(SearchHit searchHit : searchHits){
                    CoursePub coursePub = new CoursePub();
                    Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
                    String id = (String) sourceAsMap.get("id");
                    coursePub.setId(id);
                    String name = (String) sourceAsMap.get("name");
                    Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                    if(highlightFields!=null){
                        HighlightField highlightFieldName = highlightFields.get("name");
                        if(highlightFieldName!=null){
                            Text[] fragments = highlightFieldName.fragments();
                            StringBuffer stringBuffer = new StringBuffer();
                            for(Text text:fragments){
                                stringBuffer.append(text);
                            }
                            name = stringBuffer.toString();
                        }

                    }
                    coursePub.setName(name);
                    String pic = (String) sourceAsMap.get("pic");
                    coursePub.setPic(pic);
                    Double price = null;
                    try{
                        if(sourceAsMap.get("pic") != null){
                            price = (Double) sourceAsMap.get("price");
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                    coursePub.setPic(pic);

                    Double price_old = null;
                    try{
                        if(sourceAsMap.get("price_old") != null){
                            price_old = (Double) sourceAsMap.get("price_old");
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                    coursePub.setPrice_old(price_old);
                    list.add(coursePub);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            queryResult.setList(list);
        }


        QueryResponseResult<CoursePub> coursePubQueryResponseResult = new QueryResponseResult<>(CommonCode.SUCCESS, queryResult);
        return coursePubQueryResponseResult;
    }


}
